<?php


namespace PKApp\Content;

use PKApp\Content\Classes\TraitContent;
use PKApp\Model\Classes\TraitModel;
use PKApp\Topic\Classes\TraitTopic;
use PKCommon\Controller\AdminController;
use PKFrame\DataHandler\Arrays;
use PKFrame\DataHandler\MatchHelper;
use PKFrame\DataHandler\Numbers;
use PKFrame\DataHandler\Pages;
use PKFrame\DataHandler\Str;

class AdminSetContent extends AdminController
{

    use TraitContent, TraitModel, TraitTopic;

    private $_modelId, $_catId;
    protected $service_content;

    public function __construct()
    {
        parent::__construct();
        if (!in_array(request()->action(), ['ApiByCreateToOtherCategory', 'ApiByCreateToTopic', 'ApiByDel'])) {
            $this->_isPower();
        }
        $this->_modelId = $this->getIdOfModel();
        $this->service_content = $this->serviceOfContent($this->_modelId);
    }

    public function Main()
    {
        $this->assign([
            'modelId' => $this->_modelId,
            'catId' => $this->_catId,
            'id' => request()->get('id'),
            'groupId' => $this->loginUser()->GroupId,
        ])->fetch('content_editor');
    }

    /**
     * 将动态内容同时发布（镜像）到其他栏目
     */
    public function ApiByCreateToOtherCategory()
    {
        $contentEntity = $categoryEntity = $siteEntity = [];
        $catList = request()->post('catList');
        Arrays::Is($catList) ?: $this->noticeByJson('CreateToOtherCategory_CatIdEmpty');
        $this->createTo($contentEntity, $categoryEntity, $siteEntity);
        foreach ($catList as $cat) {
            if (is_array($cat)) {
                $to_catId = Numbers::To($cat['catId']);
                Numbers::IsId($to_catId) ?: $this->noticeByJson('CreateToOtherCategory_CatIdEmpty');
                $to_modelId = Numbers::To($cat['modelId']);
                Numbers::IsId($to_modelId) ?: $this->noticeByJson('CreateToOtherCategory_ModelIdEmpty');
                if ($to_catId == $categoryEntity['id']) {
                    $this->noticeByJson('CreateToOtherCategory_IdError');
                }
                if ($to_modelId != $categoryEntity['modelId']) {
                    $this->noticeByJson('CreateToOtherCategory_ModelIdError');
                }
                $this->service_content->Add(
                    $this->_mirroringContent($contentEntity, $categoryEntity, $siteEntity)
                );
            }
        }
        $this->inputSuccess();
    }

    private function _mirroringContent(array $from_content, array $categoryEntity, array $siteEntity): array
    {
        $mirroring_data = array_merge($from_content, [
            'url' => self::UrlPathOfContent(
                $categoryEntity, $categoryEntity['template'],
                $from_content, $siteEntity['Site_Path']),
            'createTime' => TIMESTAMP,
            'updateTime' => TIMESTAMP,
            'catId' => $categoryEntity['id'],
            'modelId' => $categoryEntity['modelId'],
            'mirroringId' => $from_content['id']
        ]);
        if (array_key_exists('id', $mirroring_data)) {
            unset($mirroring_data['id']);
        }
        return $mirroring_data;
    }

    protected function createTo(&$contentEntity, &$categoryEntity, &$siteEntity)
    {
        $contentEntity = request()->post('content');
        is_array($contentEntity) ?: $this->noticeByJson('CreateToOtherCategory_ContentEmpty');
        $categoryEntity = request()->post('category');
        is_array($categoryEntity) ?: $this->noticeByJson('CreateToOtherCategory_categoryEmpty');
        // get content url
        $siteEntity = $this->serviceOfSite()->interface_getEntityById(
            $this->loginUser()->SiteId, ['Site_Path']
        );
    }

    /**
     * 将内容添加到专题中
     */
    public function ApiByCreateToTopic()
    {
        static $lang_app = 'topic';
        $contentEntity = $categoryEntity = $siteEntity = [];
        $list_topic = request()->post('topicList');
        Arrays::Is($list_topic) ?: $this->noticeByJson('Empty_topicCreate', $lang_app);
        $this->createTo($contentEntity, $categoryEntity, $siteEntity);
        $TC_data = ['contentTitle' => $contentEntity['title'],
            'contentUrl' => self::UrlPathOfContent(
                $categoryEntity, $categoryEntity['template'],
                $contentEntity, $siteEntity['Site_Path']),
            'contentImage' => $contentEntity['thumb'],
            'contentModelId' => $contentEntity['modelId'],
            'contentCatId' => $contentEntity['catId'],
            'contentCatName' => $categoryEntity['name'],
        ];
        $service_TC = $this->serviceOfTopicContent();
        $list_exists = $service_TC->GetList(
            ['contentId' => $TC_data['contentId'], 'siteId' => $this->loginUser()->SiteId],
            ['topicId', 'id', 'topicTypeId']);
        foreach ($list_topic as $item_topic) {
            $to_topicId = Numbers::To($item_topic['topicId']);
            Numbers::IsId($to_topicId) ?: $this->noticeByJson('Empty_TopicId', $lang_app);
            $to_topicTitle = Arrays::GetKey('topicTitle', $item_topic, 'Empty_topicTitle', $lang_app);
            $to_topicTypeId = Numbers::To($item_topic['topicTypeId']);
            Numbers::IsId($to_topicTypeId) ?: $this->noticeByJson('Empty_TopicTypeId', $lang_app);
            $to_topicTypeName = Arrays::GetKey('topicTypeName', $item_topic, 'Empty_topicTypeName', $lang_app);
            if (Arrays::Is($list_exists)) {
                $tmp_exists = array_filter($list_exists, function ($item_exists) use ($to_topicId, $to_topicTypeId) {
                    return $item_exists['topicId'] == $to_topicId && $item_exists['topicTypeId'] == $to_topicTypeId ? $item_exists : [];
                });
                if (Arrays::Is($tmp_exists)) {
                    $tmp_exists = end($tmp_exists);
                    $service_TC->UpdateById($tmp_exists['id'], array_merge($TC_data, ['isDeleted' => 0,]));
                    continue;
                }
            }
            $insert_data = array_merge($TC_data, [
                'createTime' => TIMESTAMP,
                'siteId' => $this->loginUser()->SiteId,
                'contentId' => $contentEntity['id'],
                'topicId' => $to_topicId, 'topicTitle' => $to_topicTitle,
                'topicTypeId' => $to_topicTypeId, 'topicTypeName' => $to_topicTypeName]);
        }
        if (isset($insert_data) && Arrays::Is($insert_data)) {
            $service_TC->Add($insert_data);
        }
        $this->inputSuccess();
    }

    protected function model(): array
    {
        in_array('changeContentBaseSetPower', $this->loginUser()->PowerByAction) ?: $this->noticeByJson('Content_PowerError');
        // 模型基本字段
        $post_base = $this->checkModel(['thumb', 'seoTitle', 'seoKeywords', 'seoDescription',]);
        $post_base = array_merge($post_base, [
            'title' => Str::strCutOfTinytext($this->checkPostFieldIsEmpty('title', 'Content_titleEmpty')),
            'userId' => $this->loginUser()->Id,
            'siteId' => $this->loginUser()->SiteId,
            'modelId' => $this->postId('modelId', 'Model_idEmpty'),
            'catId' => $this->_catId,
            'updateTime' => TIMESTAMP, 'isDeleted' => 0,
        ]);
        // SEO
        !empty($post_base['seoTitle']) ? $post_base['seoTitle'] = Str::strCutOfTinytext($post_base['seoTitle']) : $post_base['seoTitle'] = $post_base['title'];
        !empty($post_base['seoKeywords']) ?: $post_base['seoKeywords'] = $post_base['title'];
        if (!empty($post_base['seoKeywords'])) {
            $post_base['seoKeywords'] = trim(str_replace('，', ',', $post_base['seoKeywords']), ',');
        }
        if (empty($post_base['seoDescription'])) {
            $post_base['seoDescription'] = $post_base['title'];
        }
        $post_base['seoKeywords'] = str_cut($post_base['seoKeywords'], 500);
        $post_base['seoDescription'] = str_cut($post_base['seoDescription'], 600);
        // 判断是否分配了扩展信息的修改权限
        if (in_array('changeContentHeightSetPower', $this->loginUser()->PowerByAction)) {
            $post_base = array_merge($post_base, $this->checkModel(['createTime', 'template', 'url',]));
            if (array_key_exists('createTime', $post_base) && !empty($post_base['createTime'])) {
                MatchHelper::MatchFormat('dateTime', $post_base['createTime'], 'Content_createTime_Error');
                $post_base['createTime'] = strtotime($post_base['createTime']);
            }
            // 内容的属性
            $list_attribute = dict('content_attribute', request()->module());
            foreach ($list_attribute as $index => $item) {
                $post_base[$index] = request()->post($index) == 'on' ? 1 : 0;
            }
            // 内容排序
            $post_base['listSort'] = Numbers::To(request()->post('listSort'));
        }
        // 模型字段
        $insertHandler = $this->modelOfToInsertData();
        $insertHandler->Get(request()->post(), $post_base['modelId']);
        !empty($post_base['thumb']) ?: $post_base['thumb'] = $insertHandler->thumb;
        $src_arr = parse_url($post_base['thumb']);
        if (Arrays::Is($src_arr) == 3 && array_key_exists('path', $src_arr)) {
            $post_base['thumb'] = '/' . ltrim($src_arr['path'], '/');
        }
        return array('base' => array_merge($post_base, $insertHandler->listField_base),
            'data' => $insertHandler->listField_data);
    }

    public function ApiByCreate()
    {
        $post = $this->model();
        if (!array_key_exists('createTime', $post['base']) || empty($post['base']['createTime'])) {
            $post['base']['createTime'] = time();
        }
        $post['base']['hits'] = rand(150, 500);
        $post['base']['id'] = $this->service_content->SaveData($post);
        $this->json($post['base']);
    }

    public function ApiByChange()
    {
        $this->_changeContent(['siteId' => $this->loginUser()->SiteId,]);
    }

    public function ApiByRecycle()
    {
        $this->_changeContent(['siteId' => $this->loginUser()->SiteId, 'isDeleted' => 1]);
    }

    private function _changeContent(array $params_query)
    {
        $id = $this->_getContentId();
        $entity = $this->service_content->GetEntity(array_merge($params_query, ['id' => $id,]));
        !Numbers::IsId($entity['mirroringId']) ?: $this->noticeByJson('mirroring_content_FailChange');
        $post = $this->model();
        array_key_exists('updateTime', $post['base']) ?: $post['base']['updateTime'] = TIMESTAMP;
        $this->service_content->SaveData($post, $id);
        $post['base']['id'] = $id;
        $this->json($post['base']);
    }

    public function ApiByDel()
    {
        $list_id = $this->_getContentIdList();
        $site_id = $this->loginUser()->SiteId;
        // 从综合方向的执行是没有的
        if (request()->has('catId', 'post')) {
            $entity_category = $this->serviceOfCategory(
                $this->loginUser()->SiteId
            )->interface_getEntityById(
                request()->post('catId')
            );
        }
        $siteEntity = $this->serviceOfSite()->interface_getEntityById(
            $site_id, ['Site_Path', 'setting']
        );
        $path_pc = $siteEntity['Site_Path'];
        $path_mobile = $siteEntity['setting']['MobileStaticsPath'];
        $entity_content = $this->service_content->GetList(['id' => $list_id], ['id', 'catId', 'url']);
        foreach ($entity_content as $item_content) {
            if (!isset($entity_category) && Numbers::IsId($item_content['catId'])) {
                $entity_category = $this->serviceOfCategory($site_id)->GetEntity(['id' => $item_content['catId']]);
            }
            if (isset($entity_category) && Arrays::Is($entity_category)) {
                $url_pc = self::UrlPathOfContent(
                    $entity_category, $entity_category['template'], $item_content, $path_pc
                );
                fileHelper()->UnLink($url_pc);
                if (!empty($path_mobile)) {
                    $url_mobile = self::UrlPathOfContent(
                        $entity_category, $entity_category['template'], $item_content, $path_mobile
                    );
                    fileHelper()->UnLink($url_mobile);
                }
            }
        }
        $this->service_content->HideById($list_id);
        $this->service_content->HideByParams(['mirroringId' => $list_id]);
        $this->serviceOfTopicContent()->HideByParams(['contentId' => $list_id,
            'contentModelId' => $this->_modelId,
            'siteId' => $site_id,
        ]);
        $this->inputSuccess();
    }

    private function _getContentIdList(): array
    {
        $contentId = request()->post('id');
        if (Numbers::IsId($contentId)) {
            $contentId = [$contentId];
        }
        Arrays::Is($contentId) ?: $this->noticeByJson('Content_idEmpty');
        $do_idList = [];
        foreach ($contentId as $id) {
            !Numbers::IsId($id) ?: $do_idList[] = $id;
        }
        return $do_idList;
    }

    public function ApiBySortIndex()
    {
        $this->service_content->UpdateById(
            $this->_getContentId(),
            ['listSort' => Numbers::To(request()->post('sortIndex'))]);
        $this->inputSuccess();
    }

    public function ApiByHits()
    {
        $this->service_content->UpdateById(
            $this->_getContentId(),
            ['hits' => Numbers::To(request()->post('hits'))]);
        $this->inputSuccess();
    }

    public function ApiByUrl()
    {
        $list_id = $this->_getContentId();
        $url = trim(request()->post('url'));
        $siteEntity = $this->serviceOfSite()->interface_getEntityById(
            $this->loginUser()->SiteId, ['Site_Path']
        );
        if (Arrays::Is($siteEntity) && array_key_exists('Site_Path', $siteEntity)
            && !empty($siteEntity['Site_Path'])) {
            $search_match = '(\/|' . $siteEntity['Site_Path'] . ')';
            $url = preg_replace($search_match, '', $url);
        }
        $params = ['url' => $url];
        $this->service_content->UpdateById($list_id, $params);
        $this->serviceOfTopicContent()->Update(['contentId' => $list_id,
            'contentModelId' => $this->_modelId,
            'siteId' => $this->loginUser()->SiteId,
        ], ['contentUrl' => $url]);
        $this->inputSuccess();
    }

    private function _getContentId(): int
    {
        return $this->postId('id', 'Content_idEmpty');
    }

    /**
     * 修改内容属性
     * 例如：头条、置顶、推荐
     */
    public function ApiByAttribute()
    {
        $attribute = request()->post('Attribute');
        $attributeList = dict('content_attribute');
        array_key_exists($attribute, $attributeList) ?: $this->noticeByJson('Content_attribute_Error');
        $contentIdList = $this->_getContentIdList();
        // 修改原有的属性，反向操作
        $contentListEntity = $this->service_content->GetList(['id' => $contentIdList], ['id', $attribute]);
        if (Arrays::Is($contentListEntity)) {
            // 取得原来的属性
            $contentListEntity = Arrays::Column($contentListEntity, $attribute, 'id');
            foreach ($contentIdList as $id) {
                // 反向操作
                $this->service_content->UpdateById($id, [$attribute => ($contentListEntity[$id] ? 0 : 1)]);
            }
        }
        $this->inputSuccess();
    }

    /**
     * 移动内容到其他的栏目中
     */
    public function ApiByMobileToOtherCategory()
    {
        $toCategoryId = $this->checkPostFieldIsEmpty('toCatId', 'Category_idEmpty');
        $contentIdList = $this->_getContentIdList();
        $this->_isEqualModelId($toCategoryId);
        $this->service_content->UpdateById($contentIdList, ['catId' => $toCategoryId]);
        $this->inputSuccess();
    }

    public function ApiByCopyToOtherCategory()
    {
        $toCategoryId = $this->checkPostFieldIsEmpty('toCatId', 'Category_idEmpty');
        $contentIdList = $this->_getContentIdList();
        $this->_isEqualModelId($toCategoryId);
        $this->service_content->CopyToOtherCategory(
            $this->service_content->GetList(['id' => $contentIdList]), $toCategoryId,
            $this->loginUser()->SiteId);
        $this->inputSuccess();
    }

    public function ApiByBatMirroringToOtherCategory()
    {
        $toCategoryId = $this->checkPostFieldIsEmpty('toCatId', 'Category_idEmpty');
        $contentIdList = $this->_getContentIdList();
        $toCategoryEntity = $this->_isEqualModelId($toCategoryId);
        $siteEntity = $this->serviceOfSite()->interface_getEntityById(
            $this->loginUser()->SiteId, ['Site_Path']
        );
        $listFrom_content = $this->service_content->GetList(['id' => $contentIdList]);
        if (Arrays::Is($listFrom_content)) {
            foreach ($listFrom_content as $item) {
                $this->service_content->Add(
                    $this->_mirroringContent($item, $toCategoryEntity, $siteEntity)
                );
            }
        }
        $this->inputSuccess();
    }

    /**
     * 检查两个栏目的模型ID是否相同
     * @param $toCategoryId
     * @return null
     */
    private function _isEqualModelId($toCategoryId)
    {
        $toCategoryEntity = $this->serviceOfCategory(
            $this->loginUser()->SiteId
        )->interface_getEntityById($toCategoryId, ['modelId']);
        $this->_modelId == $toCategoryEntity['modelId'] ?: $this->noticeByJson('Content_mobileCategory_Error');
        return $toCategoryEntity;
    }

    /**
     * 检查当前栏目的编辑权限和阅读权限
     */
    private function _isPower()
    {
        if (request()->has('catId', 'get')) {
            $this->_catId = $this->getId('catId', 'Category_idEmpty');
        } else {
            $this->_catId = $this->postId('catId', 'Category_idEmpty');
        }
        $categoryEntity_now = $this->serviceOfCategory(
            $this->loginUser()->SiteId
        )->interface_getEntityById(
            $this->_catId, ['power']
        );
        if (is_array($categoryEntity_now) && array_key_exists('power', $categoryEntity_now) && is_array($categoryEntity_now['power'])) {
            $power = $categoryEntity_now['power'];
            if (array_key_exists('EditGroup', $power) && !empty($power['EditGroup'])) {
//                可编辑的权限，当不为空时，则执行以下
                $group_edit = explode(',', $power['EditGroup']);
                if (!in_array($this->loginUser()->GroupId, $group_edit)) {
//                    不在设置范围内的是受控制的范围
                    request()->action() == 'Main' ? $this->noticeByPage('Content_PowerError') : $this->noticeByJson('Content_PowerError');
                }
            }
        }
    }
}